home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 3
/
Cream of the Crop 3.iso
/
comm
/
wnos5src.zip
/
ENET.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-21
|
3KB
|
139 lines
/* Stuff generic to all Ethernet controllers */
#include <stdio.h>
#include <dos.h>
#include "global.h"
#include "config.h"
#ifdef ETHER
#include "mbuf.h"
#include "iface.h"
#include "timer.h"
#include "arp.h"
#include "ip.h"
#include "enet.h"
char Ether_bdcst[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
/* Convert Ethernet header in host form to network mbuf */
static struct mbuf *
htonether(struct ether *ether,struct mbuf *data)
{
struct mbuf *bp = pushdown(data,ETHERLEN);
char *cp = bp->data;
memcpy(cp,ether->dest,EADDR_LEN);
cp += EADDR_LEN;
memcpy(cp,ether->source,EADDR_LEN);
cp += EADDR_LEN;
put16(cp,ether->type);
return bp;
}
/* Extract Ethernet header */
int
ntohether(struct ether *ether,struct mbuf **bpp)
{
pullup(bpp,ether->dest,EADDR_LEN);
pullup(bpp,ether->source,EADDR_LEN);
ether->type = pull16(bpp);
return ETHERLEN;
}
/* Format an Ethernet address into a printable ascii string */
char *
pether(char *out,char *addr)
{
sprintf(out,"%02x:%02x:%02x:%02x:%02x:%02x",
uchar(addr[0]),uchar(addr[1]),
uchar(addr[2]),uchar(addr[3]),
uchar(addr[4]),uchar(addr[5]));
return out;
}
/* Convert an Ethernet address from Hex/ASCII to binary */
int
gether(char *out,char *cp)
{
int i;
for(i = 6; i != 0; i--) {
*out++ = htoi(cp);
if((cp = strchr(cp,':')) == NULLCHAR) /* Find delimiter */
break;
cp++; /* and skip over it */
}
return i;
}
/* Send an IP datagram on Ethernet */
int
enet_send(
struct mbuf *bp, /* Buffer to send */
struct iface *iface, /* Pointer to interface control block */
int32 gateway, /* IP address of next hop */
int prec,
int del,
int tput,
int rel)
{
char *egate;
if((egate = res_arp(iface,ARP_ETHER,gateway,bp)) != NULLCHAR)
return (*iface->output)(iface,egate,iface->hwaddr,IP_TYPE,bp);
return 0;
}
/* Send a packet with Ethernet header */
int
enet_output(
struct iface *iface, /* Pointer to interface control block */
char *dest, /* Destination Ethernet address */
char *source, /* Source Ethernet address */
int16 type, /* Type field */
struct mbuf *data) /* Data field */
{
struct ether ep;
struct mbuf *bp;
memcpy(ep.dest,dest,EADDR_LEN);
memcpy(ep.source,source,EADDR_LEN);
ep.type = type;
bp = htonether(&ep,data);
iface->lastsent = secclock();
iface->rawsndcnt++;
return (*iface->raw)(iface,bp);
}
/* Process incoming Ethernet packets. Shared by all ethernet drivers. */
void
eproc(struct iface *iface,struct mbuf *bp)
{
struct ether hdr;
/* Remove Ethernet header and kick packet upstairs */
ntohether(&hdr,&bp);
if(memcmp(hdr.dest,iface->hwaddr,EADDR_LEN) &&
memcmp(hdr.dest,Ether_bdcst,EADDR_LEN)){
free_p(bp);
return;
}
switch(hdr.type){
case ARP_TYPE:
case REVARP_TYPE:
arp_input(iface,bp);
break;
case IP_TYPE:
ip_route(iface,NULLIF,bp,hdr.dest[0] & 1);
break;
default:
free_p(bp);
break;
}
}
#endif /* ETHER */